package nc.ui.so.m30.billui.action;

import java.awt.event.ActionEvent;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import nc.desktop.ui.Workbench;
import nc.desktop.ui.WorkbenchEnvironment;
import nc.itf.pubapp.pub.exception.IResumeException;
import nc.pubitf.credit.accountcheck.IAccountCheckMessageService;
import nc.pubitf.credit.creditcheck.ICreditCheckMessageService;
import nc.ui.ml.NCLangRes;
import nc.ui.pub.beans.MessageDialog;
import nc.ui.pubapp.pub.common.context.PFlowContext;
import nc.ui.pubapp.pub.locator.NCUILocator;
import nc.ui.pubapp.uif2app.actions.RefreshSingleAction;
import nc.ui.pubapp.uif2app.actions.pflow.SaveScriptAction;
import nc.ui.pubapp.uif2app.model.BillManageModel;
import nc.ui.so.m30.billui.view.SaleOrderBillForm;
import nc.ui.so.pub.keyvalue.CardKeyValue;
import nc.ui.uif2.UIState;
import nc.ui.uif2.editor.IEditor;
import nc.vo.credit.exception.CreditCheckException;
import nc.vo.credit.exception.OverPeriodDayCheckException;
import nc.vo.credit.exception.OverPeriodInnerDayCheckException;
import nc.vo.credit.exception.OverPeriodMoneyCheckException;
import nc.vo.ct.exception.CtToleranceException;
import nc.vo.ic.pub.exp.ReserveCheckException;
import nc.vo.ml.AbstractNCLangRes;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.opc.opcpub.execption.CustomerPOToleranceException;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.MathTool;
import nc.vo.pubapp.pattern.pub.PubAppTool;
import nc.vo.pubapp.pflow.PfUserObject;
import nc.vo.pubapp.res.NCModule;
import nc.vo.scmpub.exp.AtpNotEnoughException;
import nc.vo.scmpub.res.BusinessCheck;
import nc.vo.so.m30.entity.OffsetTempVO;
import nc.vo.so.m30.entity.SaleOrderBVO;
import nc.vo.so.m30.entity.SaleOrderHVO;
import nc.vo.so.m30.entity.SaleOrderUserObject;
import nc.vo.so.m30.entity.SaleOrderVO;
import nc.vo.so.m30.sobalance.entity.SoBalanceVO;
import nc.vo.so.pub.enumeration.BillStatus;
import nc.vo.so.pub.exeception.PreOrderToleranceException;

public class SaleOrderSaveAction extends SaveScriptAction
{
  private static final long serialVersionUID = -3977967248003982108L;
  private RefreshSingleAction refreshAction;
  private Set<String> resumeExcType;

  public SaleOrderSaveAction()
  {
    this.resumeExcType = new HashSet();
    this.resumeExcType.add(BusinessCheck.ATPCheck.getCheckCode());
    this.resumeExcType.add(BusinessCheck.CreditCheck.getCheckCode());
    this.resumeExcType.add(BusinessCheck.CreditOverPeriodMoneyCheck.getCheckCode());

    this.resumeExcType.add(BusinessCheck.CreditOverPeriodDayCheck.getCheckCode());

    this.resumeExcType.add(BusinessCheck.CreditOverPeriodInnerDayCheck.getCheckCode());

    this.resumeExcType.add(BusinessCheck.PreOrderToleranceCheck.getCheckCode());
    this.resumeExcType.add(BusinessCheck.CtToleranceCheck.getCheckCode());
    this.resumeExcType.add(BusinessCheck.CustomerPOToleranceCheck.getCheckCode());

    this.resumeExcType.add(BusinessCheck.ReserveCheck.getCheckCode());
  }

  public void doAction(ActionEvent e) throws Exception
  {
    if (getModel().getUiState() == UIState.EDIT) {
      Object obj = this.editor.getValue();
      int index = getModel().findBusinessData(obj);
      if (index == -1) {
        ExceptionUtils.wrappBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0019"));
      }

      checkGathering();
      SaleOrderVO newVO = (SaleOrderVO)obj;

      reSetBillStatusForNoPass(newVO);
    }
    super.doAction(e);
    doAfterAction();
  }

  private void doAfterAction()
  {
    SaleOrderBillForm billform = (SaleOrderBillForm)this.editor;
    CardKeyValue keyValue = new CardKeyValue(billform.getBillCardPanel());
    UFDouble thisreceivemny = keyValue.getHeadUFDoubleValue("nthisreceivemny");

    UFDouble receivedmny = keyValue.getHeadUFDoubleValue("nreceivedmny");

    UFDouble totalorigmny = keyValue.getHeadUFDoubleValue("ntotalorigmny");

    UFDouble receivedmny_new = MathTool.add(thisreceivemny, receivedmny);

    if (MathTool.absCompareTo(receivedmny_new, totalorigmny) > 0) {
      receivedmny_new = totalorigmny;
    }

    keyValue.setHeadValue("nreceivedmny", receivedmny_new);
    keyValue.setHeadValue("nthisreceivemny", null);
  }

  public void doBeforAction()
  {
    SaleOrderBillForm billform = (SaleOrderBillForm)this.editor;
    if (null != billform) {
      PfUserObject pfUserObj = getFlowContext().getUserObj();
      pfUserObj = (pfUserObj == null) ? new PfUserObject() : pfUserObj;
      SaleOrderUserObject userobj = new SaleOrderUserObject();

      OffsetTempVO tempvo = billform.getTempvo();
      userobj.setOffsetTempVO(tempvo);

      SoBalanceVO sobalancevo = billform.getSobalancevo();
      userobj.setSoBalanceVO(sobalancevo);

      UFDouble thisGatheringMny = billform.getThisGatheringMny();
      userobj.setThisGatheringMny(thisGatheringMny);
      pfUserObj.setUserObject(userobj);
      getFlowContext().setUserObj(pfUserObj);
    }
  }

  private void checkGathering()
  {
    SaleOrderVO saleorder = (SaleOrderVO)this.editor.getValue();

    SaleOrderHVO hvo = saleorder.getParentVO();
    if (null == hvo) {
      return;
    }

    UFBoolean bpreceiveflag = hvo.getBpreceiveflag();

    UFDouble npreceivequota = hvo.getNpreceivequota();

    UFDouble npreceivemny = hvo.getNpreceivemny();

    if ((!(bpreceiveflag.booleanValue())) || (MathTool.compareTo(npreceivequota, npreceivemny) >= 0))
      return;
    StringBuilder errMsg = new StringBuilder();
    errMsg.append(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0283"));

    errMsg.append(hvo.getVbillcode());
    errMsg.append(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0468"));

    ExceptionUtils.wrappBusinessException(errMsg.toString());
  }

  public RefreshSingleAction getreFreshAction()
  {
    return this.refreshAction;
  }

  public void setRefreshAction(RefreshSingleAction refreshAction1) {
    this.refreshAction = refreshAction1;
  }

  protected boolean isResume(IResumeException resumeInfo)
  {
    String exceptiontype = resumeInfo.getBusiExceptionType();
    boolean isReserveCheck = true;

    if (resumeInfo instanceof ReserveCheckException) {
      isReserveCheck = processReserveCheck(resumeInfo);
    }
    else if ((PubAppTool.isNull(exceptiontype)) || (!(this.resumeExcType.contains(exceptiontype))))
    {
      ExceptionUtils.wrappException((Exception)resumeInfo);
    }

    boolean isATPResume = processATPCheck(resumeInfo);

    boolean isCCResume = processCreditCheck(resumeInfo);

    boolean isCOPMCResume = processCreditOverPeriodMoneyCheck(resumeInfo);

    boolean isCOPDCResume = processCreditOverPeriodDayCheck(resumeInfo);

    boolean isCOPIDCResume = processCreditOverPeriodInnerDayCheck(resumeInfo);

    boolean is38ToleranceResume = process38ToleranceCheck(resumeInfo);

    boolean isopcToleranceResume = processOpcToleranceCheck(resumeInfo);

    boolean isCtToleranceResume = processCtToleranceCheck(resumeInfo);

    return ((isATPResume) && (isCCResume) && (isCOPMCResume) && (isCOPDCResume) && (isCOPIDCResume) && (is38ToleranceResume) && (isopcToleranceResume) && (isCtToleranceResume) && (isReserveCheck));
  }

  private boolean processOpcToleranceCheck(IResumeException resumeInfo)
  {
    boolean isResume = true;
    int back = 0;
    if (BusinessCheck.CustomerPOToleranceCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      back = MessageDialog.showYesNoDlg(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), NCLangRes.getInstance().getStrByID("4006011_0", "04006011-0362"), ((CustomerPOToleranceException)resumeInfo).getMessage());

      if (4 == back) {
        PfUserObject userObj = getFlowContext().getUserObj();
        userObj = (userObj == null) ? new PfUserObject() : userObj;
        userObj.getBusinessCheckMap().put(BusinessCheck.CustomerPOToleranceCheck.getCheckCode(), Boolean.FALSE);

        getFlowContext().setUserObj(userObj);
      }
      else {
        isResume = false;
      }
    }
    return isResume;
  }

  private boolean processCtToleranceCheck(IResumeException resumeInfo)
  {
    boolean isResume = true;

    if (BusinessCheck.CtToleranceCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      int back = MessageDialog.showYesNoDlg(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), NCLangRes.getInstance().getStrByID("4006011_0", "04006011-0437"), ((CtToleranceException)resumeInfo).getMessage());

      if (4 == back) {
        PfUserObject userObj = getFlowContext().getUserObj();
        userObj = (userObj == null) ? new PfUserObject() : userObj;
        userObj.getBusinessCheckMap().put(BusinessCheck.CtToleranceCheck.getCheckCode(), Boolean.FALSE);

        getFlowContext().setUserObj(userObj);
      }
      else {
        isResume = false;
      }
    }
    return isResume;
  }

  protected Object[] processBefore(Object[] vos)
  {
    for (Object vo : vos) {
      SaleOrderVO saleordervo = (SaleOrderVO)vo;
      SaleOrderBVO[] bvos = saleordervo.getChildrenVO();
      if ((bvos != null) && (bvos.length != 0))
        continue;
      ExceptionUtils.wrappBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0020"));
    }

    return vos;
  }

  private boolean process38ToleranceCheck(IResumeException resumeInfo) {
    boolean isResume = true;
    int back = 0;
    if (BusinessCheck.PreOrderToleranceCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      back = MessageDialog.showYesNoDlg(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), NCLangRes.getInstance().getStrByID("4006011_0", "04006011-0243"), ((PreOrderToleranceException)resumeInfo).getMessage());

      if (4 == back) {
        PfUserObject userObj = getFlowContext().getUserObj();
        userObj = (userObj == null) ? new PfUserObject() : userObj;
        userObj.getBusinessCheckMap().put(BusinessCheck.PreOrderToleranceCheck.getCheckCode(), Boolean.FALSE);

        getFlowContext().setUserObj(userObj);
      }
      else {
        isResume = false;
      }
    }
    return isResume;
  }

  private boolean processATPCheck(IResumeException resumeInfo)
  {
    boolean isResume = true;
    int back = 0;
    if (BusinessCheck.ATPCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      back = MessageDialog.showYesNoDlg(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), NCLangRes.getInstance().getStrByID("4006011_0", "04006011-0244"), ((AtpNotEnoughException)resumeInfo).getMessage());

      if (4 == back) {
        isResume = true;
        PfUserObject userObj = getFlowContext().getUserObj();
        userObj = (userObj == null) ? new PfUserObject() : userObj;
        userObj.getBusinessCheckMap().put(BusinessCheck.ATPCheck.getCheckCode(), Boolean.valueOf(!(isResume)));

        getFlowContext().setUserObj(userObj);
      }
      else {
        isResume = false;
      }
    }

    return isResume;
  }

  private boolean processReserveCheck(IResumeException resumeInfo) {
    boolean isResume = true;
    int back = 0;
    back = MessageDialog.showYesNoDlg(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), NCLangRes.getInstance().getStrByID("4006011_0", "04006011-0245"), ((ReserveCheckException)resumeInfo).getMessage());

    if (4 == back) {
      isResume = true;
      PfUserObject userObj = getFlowContext().getUserObj();
      userObj = (userObj == null) ? new PfUserObject() : userObj;
      userObj.getBusinessCheckMap().put(BusinessCheck.ReserveCheck.getCheckCode(), Boolean.valueOf(!(isResume)));

      getFlowContext().setUserObj(userObj);
    }
    else {
      isResume = false;
    }

    return isResume;
  }

  private boolean processCreditCheck(IResumeException resumeInfo)
  {
    boolean isResume = true;

    if (BusinessCheck.CreditCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      ICreditCheckMessageService service = (ICreditCheckMessageService)NCUILocator.getInstance().lookup(ICreditCheckMessageService.class, NCModule.CREDIT);
      try
      {
        isResume = service.showMessage(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), (CreditCheckException)resumeInfo);
      }
      catch (BusinessException e)
      {
        ExceptionUtils.wrappException(e);
      }

      PfUserObject userObj = getFlowContext().getUserObj();
      if (userObj == null) {
        userObj = new PfUserObject();
      }
      userObj.getBusinessCheckMap().put(BusinessCheck.CreditCheck.getCheckCode(), Boolean.valueOf(!(isResume)));

      getFlowContext().setUserObj(userObj);
    }
    return isResume;
  }

  private boolean processCreditOverPeriodDayCheck(IResumeException resumeInfo)
  {
    boolean isResume = true;
    if (BusinessCheck.CreditOverPeriodDayCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      IAccountCheckMessageService service = (IAccountCheckMessageService)NCUILocator.getInstance().lookup(IAccountCheckMessageService.class, NCModule.CREDIT);
      try
      {
        isResume = service.showMessage(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), ((OverPeriodDayCheckException)resumeInfo).getHintMessage());
      }
      catch (BusinessException e)
      {
        ExceptionUtils.wrappException(e);
      }

      PfUserObject userObj = getFlowContext().getUserObj();
      if (userObj == null) {
        userObj = new PfUserObject();
      }
      userObj.getBusinessCheckMap().put(BusinessCheck.CreditOverPeriodDayCheck.getCheckCode(), Boolean.valueOf(!(isResume)));

      getFlowContext().setUserObj(userObj);
    }
    return isResume;
  }

  private boolean processCreditOverPeriodInnerDayCheck(IResumeException resumeInfo)
  {
    boolean isResume = true;
    if (BusinessCheck.CreditOverPeriodInnerDayCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      IAccountCheckMessageService service = (IAccountCheckMessageService)NCUILocator.getInstance().lookup(IAccountCheckMessageService.class, NCModule.CREDIT);
      try
      {
        isResume = service.showMessage(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), ((OverPeriodInnerDayCheckException)resumeInfo).getHintMessage());
      }
      catch (BusinessException e)
      {
        ExceptionUtils.wrappException(e);
      }

      PfUserObject userObj = getFlowContext().getUserObj();
      if (userObj == null) {
        userObj = new PfUserObject();
      }
      userObj.getBusinessCheckMap().put(BusinessCheck.CreditOverPeriodInnerDayCheck.getCheckCode(), Boolean.valueOf(!(isResume)));

      getFlowContext().setUserObj(userObj);
    }
    return isResume;
  }

  private boolean processCreditOverPeriodMoneyCheck(IResumeException resumeInfo)
  {
    boolean isResume = true;
    if (BusinessCheck.CreditOverPeriodMoneyCheck.getCheckCode().equals(resumeInfo.getBusiExceptionType()))
    {
      IAccountCheckMessageService service = (IAccountCheckMessageService)NCUILocator.getInstance().lookup(IAccountCheckMessageService.class, NCModule.CREDIT);
      try
      {
        isResume = service.showMessage(WorkbenchEnvironment.getInstance().getWorkbench().getParent(), ((OverPeriodMoneyCheckException)resumeInfo).getHintMessage());
      }
      catch (BusinessException e)
      {
        ExceptionUtils.wrappException(e);
      }

      PfUserObject userObj = getFlowContext().getUserObj();
      if (userObj == null) {
        userObj = new PfUserObject();
      }
      userObj.getBusinessCheckMap().put(BusinessCheck.CreditOverPeriodMoneyCheck.getCheckCode(), Boolean.valueOf(!(isResume)));

      getFlowContext().setUserObj(userObj);
    }
    return isResume;
  }

  private void reSetBillStatusForNoPass(SaleOrderVO vo) {
    if (vo.getParentVO().getFstatusflag().intValue() != BillStatus.NOPASS.getIntValue())
      return;
    vo.getParentVO().setFstatusflag(BillStatus.FREE.getIntegerValue());
    this.editor.setValue(vo);
  }
}